Skip to content

feat(logging): tag logs with a per-session ID - #1073

Merged
aqandrew merged 8 commits into
mainfrom
aqandrew/devex-661-session-logger
Aug 17, 2026
Merged

feat(logging): tag logs with a per-session ID#1073
aqandrew merged 8 commits into
mainfrom
aqandrew/devex-661-session-logger

Conversation

@aqandrew

@aqandrew aqandrew commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

What

Introduce a per-session identifier and make the extension tag every log line with it, so all logs for a session can be correlated by searching a single ID.

This is Phase 1 of 3 for DEVEX-661 — "VS Code: add session_id to all requests, logs, existing telemetry, and CLI invocations".

Changes

  • Add SessionLogger (src/logging/sessionLogger.ts) — a Logger that wraps the Coder output channel and prefixes every message with [<sessionId>].
  • Generate the session ID once in ServiceContainer (reusing the existing newSessionId() that already backs the telemetry session, so logs, telemetry, requests, and the CLI all share one ID), and expose it via getSessionId() for the later phases.

Because every service already receives Logger by injection, session-tagged logging propagates with no call-site changes.

Design notes

The code owner (Ehab) suggested composing the session ID and the VS Code logger inside container.ts's ServiceContainer; this PR follows that approach. The telemetry sessionId from newSessionId() is the RFC session_id (confirmed with Ehab — reuse it rather than minting a second ID).

Testing

  • pnpm typecheck, targeted pnpm lint, and pnpm test:extension (full suite: 2108 passing).
  • New unit tests for SessionLogger prefixing and argument forwarding.
Implementation plan (DEVEX-661)

Thread a single per-session identifier (16-byte / 32-char lowercase hex) so that
logs, API requests, existing telemetry, and the CLI ssh invocation the
extension drives can all be correlated by one session_id.

In-scope RFC requirements

Req Summary Where
1 Generate 16-byte / 32-hex session ID Reuse existing newSessionId()
2 Session ID on every client log Phase 1 (this PR)
3 session_id on every API request via baggage Phase 2
4.2 session_id on VS Code telemetry Phase 2 (already covered by reusing the ID)
5.2/5.3 CODER_TRACE_SESSION_ID via process.env + terminal env collection Phase 2
7 Log workspace/agent/lifecycle state changes at info Phase 3
16 Default --log-dir + old-log cleanup Already implemented — verify only

Out of scope: coderd tracing middleware (req 6), agent/coordination-protocol
changes and the CLI ssh subcommand behavior (reqs 8–15) live in coder/coder.
Req 13 (in-memory log buffer flushed on connection failure) is deferred to a
follow-up.

Key decisions

  • D1 (resolved): the telemetry sessionId is the RFC session_id — one ID,
    generated once in ServiceContainer.
  • D2: session scope is per activation; Remote-SSH opens each workspace in a fresh
    activation, so container-scoped ≈ per-connection.
  • D3 (resolved): prefix every log line with the full 32-hex ID as
    [<sessionId>] <message>.
  • D4: baggage: session_id=<hex> header.

Phases

  1. Session ID + SessionLogger composition in the container (this PR).
  2. Thread the ID to API requests (baggage), telemetry (already covered), and the
    CLI via CODER_TRACE_SESSION_ID on process.env + the terminal env
    collection.
  3. Log workspace / agent / lifecycle state transitions at info.

🤖 Generated by Coder Agents.

Add SessionLogger, which wraps the Coder output channel and prefixes
every message with the activation's session ID so all log lines for a
session can be correlated by a single ID. Generate the ID once in the
ServiceContainer, reuse it as the telemetry session ID, and expose it
via getSessionId() for downstream consumers.
@linear-code

linear-code Bot commented Aug 11, 2026

Copy link
Copy Markdown

DEVEX-661

@aqandrew
aqandrew force-pushed the aqandrew/devex-661-session-logger branch from 615ea3b to 445ab75 Compare August 12, 2026 22:00
Comment thread src/core/container.ts Outdated
Comment thread src/logging/sessionLogger.ts Outdated
Comment thread src/logging/sessionLogger.ts Outdated
@aqandrew
aqandrew force-pushed the aqandrew/devex-661-session-logger branch from 445ab75 to 615ea3b Compare August 13, 2026 18:46
Replace the SessionLogger class with a prefixLogger(inner, prefix) factory
that wraps a Logger and prefixes every message, and rename the module to
prefixLogger.ts. The prefix is now generic (a session ID, a workspace name,
etc.); the caller passes the bracketed session prefix. Addresses review
feedback on #1073.
Comment thread src/core/container.ts
Comment on lines +51 to +52
// One session ID per activation, shared by logs, API requests,
// telemetry, and the CLI so all data for a session correlates.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this comment will go once we have a the file with a session ID defined at runtime

Prefix logs with [session <shortId>] and render the HTTP request ID as
[request <shortId>] so a line clearly identifies both IDs, e.g.
'[session ece5f89f] <- [request 38b0a2b4] 200 GET ...'. The full session
ID is unchanged on the wire; only the log representation is shortened.
@aqandrew
aqandrew merged commit 5fbc409 into main Aug 17, 2026
11 checks passed
@aqandrew
aqandrew deleted the aqandrew/devex-661-session-logger branch August 17, 2026 20:49
aqandrew added a commit that referenced this pull request Aug 17, 2026
…v var (#1074)

## What

Propagate the session ID from Phase 1 to outbound API requests and to
the CLI, so server-side logs, telemetry, and the spawned `coder ssh`
process can all be correlated with the extension's session.

This is **Phase 2 of 3** for
[DEVEX-661](https://linear.app/codercom/issue/DEVEX-661). It builds on
#1073.

## Changes

- **Requests (RFC req 3):** add a `sessionId` argument to
`CoderApi.create` and attach the session ID to every request via the W3C
`baggage` header using the `client_session_id` key (`baggage:
client_session_id=<hex>`), on both the REST default headers and the
WebSocket handshake headers. Threaded through all `CoderApi.create` call
sites, including the pre-auth OAuth/login/deployment clients, so every
request carries it.
- **Telemetry (RFC req 4.2):** already satisfied — the shared ID is the
telemetry `sessionId`, which ships on every event's context.
- **CLI (RFC reqs 5.2/5.3):** extend `applySshEnvironment` to also set
`CODER_TRACE_SESSION_ID` on both `process.env` and the terminal
environment collection, so the spawned `coder ssh` ProxyCommand reuses
the plugin's session ID instead of generating its own.

## Testing

- `pnpm typecheck`, targeted `pnpm lint`, full `pnpm test:extension`
(2108 passing).
- New tests: `baggage: client_session_id=<hex>` present/absent on
`CoderApi`; `CODER_TRACE_SESSION_ID` applied to `process.env` and the
terminal collection and restored on dispose.

---

🤖 Generated by Coder Agents.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants